package com.hmall.search.listener;

import com.alibaba.fastjson.JSON;
import com.hmall.api.client.ItemClient;
import com.hmall.api.dto.ItemDTO;
import com.hmall.common.utils.BeanUtils;
import com.hmall.search.domain.po.ItemDoc;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.http.HttpHost;
import org.elasticsearch.ElasticsearchException;
import org.elasticsearch.action.delete.DeleteRequest;
import org.elasticsearch.action.index.IndexRequest;
import org.elasticsearch.action.index.IndexResponse;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestClient;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.common.xcontent.XContentType;
import org.springframework.amqp.core.ExchangeTypes;
import org.springframework.amqp.rabbit.annotation.Exchange;
import org.springframework.amqp.rabbit.annotation.Queue;
import org.springframework.amqp.rabbit.annotation.QueueBinding;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.stereotype.Component;

import java.io.IOException;

@Slf4j
@Component
@RequiredArgsConstructor
public class ItemListener {

    private final RestHighLevelClient client = new RestHighLevelClient(RestClient.builder(HttpHost.create("http://127.0.0.1:9200")));

    private final ItemClient itemClient;

    // 监听消息队列消息，并对ES索引库进行新增或更新
    @RabbitListener(bindings = @QueueBinding(
            value = @Queue(name = "search.item.index.queue", durable = "true"),
            exchange = @Exchange(name = "search.direct", type = ExchangeTypes.DIRECT),
            key = "item.index"
    ))
    public void listenerItemIndex(Long id) throws IOException {
        try {
            // 1.根据id查询商品信息
            ItemDTO item = itemClient.queryItemById(id);
            // 2. 将DTO转换为DOC
            ItemDoc doc = BeanUtils.copyBean(item, ItemDoc.class);
            // 3.准备Request对象
            IndexRequest request = new IndexRequest("items").id(doc.getId());
            // 4. 准备请求参数
            request.source(JSON.toJSONString(doc), XContentType.JSON);
            // 4. 发送请求
            IndexResponse response = client.index(request, RequestOptions.DEFAULT);

            // 5.输出日志
            log.debug("索引操作结果: {}", response.getResult().name());
            log.info("文档 {} 索引成功", response.getId());
        } catch (ElasticsearchException e) {
            log.error("ES操作失败 [商品ID: {}]", id, e);
        }
    }

    // 监听消息队列的消息，删除商品
    @RabbitListener(bindings = @QueueBinding(
            value = @Queue(name = "search.item.delete.queue", durable = "true"),
            exchange = @Exchange(name = "search.direct", type = ExchangeTypes.DIRECT),
            key = "item.delete"
    ))
    public void listenerItemDelete(Long id) throws IOException {
        DeleteRequest request = new DeleteRequest("items").id(String.valueOf(id));
        client.delete(request, RequestOptions.DEFAULT);
    }

    // 监听消息队列的消息，更新商品的状态
    @RabbitListener(bindings = @QueueBinding(
            value = @Queue(name = "search.item.status.queue", durable = "true"),
            exchange = @Exchange(name = "search.direct", type = ExchangeTypes.DIRECT),
            key = "item.update.status"
    ))
    public void listenerItemStatus(Long id) throws IOException {
        // 1.根据id查询商品信息
        ItemDTO item = itemClient.queryItemById(id);
        if (item.getSold() == 1) this.listenerItemDelete(id);
        else if (item.getStatus() == 0) this.listenerItemIndex(id);
    }

}
